package view;

import java.awt.GridLayout;
import java.lang.reflect.Field;

import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import debugger.Debugger;

import behavior.Parameters;

/**
 * this is the panel for holding RangeSliders for the values contained in Debugger and Parameters
 * this is so that if values are added to either classes, it is extremely easy to add to this panel
 * by calling the appropriate method
 * @author ga-youngjoung
 *
 */
public class ParametersandDebuggerPanel extends JPanel{
	
    private Parameters myParameters;
    private Debugger myDebugger;
    
    public ParametersandDebuggerPanel(Parameters parameters, Debugger debugger) {
    	myParameters = parameters;
    	myDebugger = debugger;
    }
    
    /**
     * ChangeListener to set a certain instance variable in Debugger
     * @author ga-youngjoung
     *
     */
    public class DebuggerChangeListener implements ChangeListener {
    	
    	private String myParameterToBeChanged;
    	
    	public DebuggerChangeListener(String parameterToBeChanged) {
    		setLayout(new GridLayout(6, 1));
    		myParameterToBeChanged = parameterToBeChanged;
    	}
    	
		public void stateChanged(ChangeEvent e) {
			JSlider source = (JSlider)e.getSource();
	        if (!source.getValueIsAdjusting()) {
	            int newParameterValue = (int)source.getValue();
	            try {
					Field parameterToChange = myDebugger.getClass().getField(myParameterToBeChanged);
					parameterToChange.setInt(myDebugger, newParameterValue);
				} catch (SecurityException e0) {
					System.err.println(e0);
				} catch (NoSuchFieldException e1) {
					System.err.println(e1);
				} catch (IllegalArgumentException e2) {
					System.err.println(e2);
				} catch (IllegalAccessException e3) {
					System.err.println(e3);
				}
	        }  
		}
    	
    }
    
    /**
     * ChangeListener to set a certain instance variable in Parameters
     * @author ga-youngjoung
     *
     */
    public class ParameterChangeListener implements ChangeListener {
    	
    	private String myParameterToBeChanged;
    	
    	public ParameterChangeListener(String parameterToBeChanged) {
    		setLayout(new GridLayout(6, 1));
    		myParameterToBeChanged = parameterToBeChanged;
    	}
    	
		public void stateChanged(ChangeEvent e) {
			JSlider source = (JSlider)e.getSource();
	        if (!source.getValueIsAdjusting()) {
	            int newParameterValue = (int)source.getValue();
	            try {
					Field parameterToChange = myParameters.getClass().getField(myParameterToBeChanged);
					parameterToChange.setInt(myParameters, newParameterValue);
				} catch (SecurityException e0) {
					System.err.println(e0);
				} catch (NoSuchFieldException e1) {
					System.err.println(e1);
				} catch (IllegalArgumentException e2) {
					System.err.println(e2);
				} catch (IllegalAccessException e3) {
					System.err.println(e3);
				}
	        }  
		}
    	
    }
    
    /**
     * adds the slider for the Parameter value along with its appropriate Change Listener to the Panel
     * @param parameterToBeChanged
     * @param title to be shown on the GUI
     * @param minValue of the RangeSlider
     * @param maxValue of the RangeSlider
     * @param setValue of the RangeSlider
     * @param spacing of the RangeSlider
     */
    public void addParameterSlider(String parameterToBeChanged, String title, int minValue, int maxValue, int setValue, int spacing) {
    	RangeSlider slider = new RangeSlider(title, minValue, maxValue, setValue, spacing);
    	slider.addChangeListener(new ParameterChangeListener(parameterToBeChanged));
    	add(slider);
    }
    
    /**
     * adds the slider for the Debugger value along with its appropriate Change Listener to the Panel
     * @param parameterToBeChanged
     * @param title to be shown on the GUI
     * @param minValue of the RangeSlider
     * @param maxValue of the RangeSlider
     * @param setValue of the RangeSlider
     * @param spacing of the RangeSlider
     */
    public void addDebuggerSlider(String parameterToBeChanged, String title, int minValue, int maxValue, int setValue, int spacing) {
    	RangeSlider slider = new RangeSlider(title, minValue, maxValue, setValue, spacing);
    	slider.addChangeListener(new DebuggerChangeListener(parameterToBeChanged));
    	add(slider);
    }
    
}
